﻿using System.Collections.Generic;
using smp.QueryDb.Structure;

namespace smp.QueryDb.Executing
{
    public class Update
    {
        private readonly Command _command;
        private readonly Table _table;
        private readonly List<UpdateTo> _parameters = new List<UpdateTo>();
        private Filter _filter;

        public Update(Table table)
        {
            if (table == null)
                throw Helper.Error("Cannot initialise Update with null table");
            if (table.IsReadOnly)
                throw Helper.Error("Cannot update data in a read only table or view");

            _table = table;
            _command = new Command();
            _command.CommandBuilder.AppendFormat("UPDATE {0} SET ", table.Declaration);
        }

        public IUpdateTo Set(Column column)
        {
            return new UpdateTo(this, column);
        }

        public Update Where(Filter filter)
        {
            _filter = filter;
            return this;
        }

        internal void AddSetParameter(UpdateTo updateTo)
        {
            _parameters.Add(updateTo);
        }

        internal ICommand GetCommand(IDbAdapter adapter)
        {
            foreach(var set in _parameters)
            {
                var parameterName = string.Format("{0}P_{1}", adapter.ParameterPix, _command.Parameters.Count);
                _command.CommandBuilder.AppendFormat(" [{0}] = {1},", set.ColumnNane, parameterName);
                _command.AddParameter(set.CreateParameter(parameterName));
            }
            _command.CommandBuilder.Remove(_command.CommandBuilder.Length - 1, 1);
            if (_filter != null)
            {
                _command.CommandBuilder.Append(" WHERE ");
                _filter.Structure.ResetParameters();
                _filter.Structure.AppendExecuteCommandBuilder(_command, _parameters.Count, _table, adapter, _command.CommandBuilder.Length - 1);
                _command.AddParameters(_filter.Structure.Parameters);
            }
            else
            {
                InstanceFactory.Log.Warning("No filter has been defined for Update command, all records will be updated.");
            }
            return _command;
        }
    }
}
